package com.proximity.service;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.stereotype.Service;

import com.beoui.geocell.GeocellManager;
import com.beoui.geocell.model.BoundingBox;
import com.proximity.core.dao.GenericDao;
import com.proximity.core.enums.LogicalEnum;
import com.proximity.core.types.DataParameter;
import com.proximity.dto.UserDto;

@Service
public class UserServiceImpl implements UserService { 

	@Autowired
	private ShaPasswordEncoder passwordEncoder;
	@Autowired
	private GenericDao genericDao;

	public UserDto find(Long id) {
		return genericDao.findObject(UserDto.class, id);
	}

	public void remove(Long id) {
		genericDao.removeObject(UserDto.class, id);
	}

	public UserDto save(UserDto user) {
		if (user.getId()==null)
			user.setPassword(passwordEncoder.encodePassword(user.getPassword(), null));
		return genericDao.saveObject(user);
	}
	
	public Collection<UserDto> findAll() {
		return genericDao.findAllObjects(UserDto.class);
	}
	
	public UserDto findByName(String name) {
		Map<String, DataParameter> map = new HashMap<String, DataParameter>();
		map.put("user", new DataParameter(name));
		Collection<UserDto> u = genericDao.findObjectsByParams(UserDto.class, map);
		if (u!=null && u.size()>0)
			return u.iterator().next();
		return null;
	}
	
	@Override
	public Collection<UserDto> findByLocation(Float latitude, Float longitude, Integer latitudeSpan, Integer longitudeSpan) {
		Float[][] points = new Float[2][2];
		
		points[0][0] = latitude + ((float)((latitudeSpan/2)/1e6));
		points[0][1] = longitude + ((float)((longitudeSpan/2)/1e6));
		points[1][0] = latitude - ((float)((latitudeSpan/2)/1e6));
		points[1][1] = longitude - ((float)((longitudeSpan/2)/1e6));

		Map<String, DataParameter> params = new HashMap<String, DataParameter>();
//		params.put("latitude", new DataParameter(points[0][0], LogicalEnum.LESS));
//		params.put("longitude", new DataParameter(points[0][1], LogicalEnum.LESS));
//		params.put("latitude", new DataParameter(points[1][0], LogicalEnum.HIGH));
//		params.put("longitude", new DataParameter(points[1][1], LogicalEnum.HIGH));
//		params.put("id", new DataParameter(id, LogicalEnum.NOT_EQUAL));
		
        BoundingBox bb = new BoundingBox(points[0][0], points[0][1], points[1][0], points[1][1]);
        List<String> cells = GeocellManager.bestBboxSearchCells(bb, null);
        
        params.put("cells", new DataParameter(cells, LogicalEnum.CONTAINS));
        
		return genericDao.findObjectsByParams(UserDto.class, params);
	}
	
}
